/*
 *  第一节 介绍
 */


import React,{useRef,useEffect,useCallback} from 'react'
import * as THREE from 'three'
import { Mesh } from 'three'
import './index.scss'

export default function Page() {

    const Body = useRef()
    // 当 React 附加了 ref 属性之后，ref.current 将直接指向 <button> DOM 元素实例。
    // 创建场景
    const Scene = useRef(new THREE.Scene()).current
    // 创建透视相机
    const Camera = useRef(new THREE.PerspectiveCamera()).current
    // 创建渲染器
    const Render = useRef(new THREE.WebGLRenderer(
        {antialias:true}
    )).current
    //创建物体组
    const Meshs = useRef([]).current

    //创建立方体
    const createRect = useCallback(
        () => {
            const rect = new THREE.BoxBufferGeometry( 2, 2, 2 )
            const meshBasicMater = new THREE.MeshBasicMaterial({color: 0x00ff00})
            const cube = new THREE.Mesh( rect, meshBasicMater );
            cube.position.set(0,0,0)
            Scene.add( cube );
            Meshs.push(cube)
        },
        [],
    )
    // 初始化函数（设置宽高）
    // useCallback返回一个缓存的回调函数
    // 把内联回调函数及依赖项数组作为参数传入 useCallback，它将返回该回调函数的 memoized 版本，
    // 该回调函数仅在某个依赖项改变时才会更新。
    // 当你把回调函数传递给经过优化的并使用引用相等性去避免非必要渲染（例如 shouldComponentUpdate）的子组件时，它将非常有用
    const init = useCallback(
        () => {
            Render.setSize(Body.current.offsetWidth,Body.current.offsetHeight)
            //设置相机参数
            Camera.aspect = Body.current.offsetWidth/Body.current.offsetHeight
            Camera.fov =45
            Camera.near = 1
            Camera.far = 1000
            Camera.position.set(0,10,20)
            Camera.lookAt(0,0,0)
            Camera.updateProjectionMatrix()
        },
        [Render,Body],
    )

        
    const renderScene = useCallback(
        () => {
            Render.render(Scene,Camera)
            Meshs.forEach(
                item =>{
                    item.rotation.x += 1/180*Math.PI
                    item.rotation.y += 1/180*Math.PI
                }
            )
            window.requestAnimationFrame(() =>renderScene())
        },
        [Render,Meshs],
    )
    // .domElement : DOMElement
    // 一个canvas，渲染器在其上绘制输出。
    // 渲染器的构造函数会自动创建(如果没有传入canvas参数);你需要做的仅仅是像下面这样将它加页面里去:
    // document.body.appendChild( renderer.domElement );

    useEffect(() => {
        console.log(1);
        //渲染器的canvas添加到div里面去
        Body.current.append(Render.domElement)
        init()
        createRect()
        renderScene()

        // return () => {
        //     cleanup  卸载时调用
        // }
    }, [])


    return (
        <div className="page" ref={Body}>
            
        </div>
    )
}
